<?php
namespace Application\model;

use Cola\Model;

/**
 * 基础登录参数处理
 * @property string $openId 平台原始account
 * @property int $sid 区服id
 * @property int $time 请求时间或平台方传递过来的参数
 * @property int $deviceCode 设备码
 * @property int $brand 品牌
 * @property int $model 设备号
 *
 */
abstract class BaseLoginModel extends Model
{
    // 游戏account
    public $account = '';
    public $account_name = ''; // 用户名
    public $cpid = '';
    public $cid = '';
    public $isChannelGm = 0;
    public $isOpenPay = 1;
    public $channelConfig = [];
    public $srid = '';
    public $isNew = 0;
    public $loginFlag = 0; // 0:新玩家 1:老玩家 2:最后登录时间非当天

    public $msg = ''; // 错误提示信息

    public $content = []; // 登录接口返回，需要返回给前端的数据
    public $serverWhere='';
    public $whitelist = 0;

    /**
     * @var string 操作系统, 0:未知 1:安卓 2:ios 3:pc
     */
    public $os;

    /**
     * 构造方法的扩展
     */
    protected function _init()
    {
        if (APP_DEV === 2) $this->isDebug = true; // 本地开启debug
    }

    public function get($k, $default = '')
    {
        $data = $_GET[$k] ?? ($_POST[$k] ?? $default);
        return $data;
    }
    
    // 定义返回结构

    /**
     * 最近登录接口结构体
     * @return array
     */
    public function lastStruct()
    {
        return [
            'accountInfo' => [],
            'serverInfo' => []
        ];
    }

    /**
     * 账号结构体
     * @param $accountInfo
     * @param $whitelist
     * @return array
     */
    public function accountStruct($accountInfo, $whitelist=0, $channelBan=1,$account='')
    {
        // 在登录时拼接一个平台名，便于适配
        $data = [
            'openId' => $account?:$accountInfo['account'],//使用account,数据库mysql可能不支持大小写
            'gameId' => realGAME_ID(),
            'status' => $accountInfo['status'],
            'authCode' => $accountInfo['authCode'],
            'banTime' => $accountInfo['banTime'] ?? 0,
            'whitelist' => $whitelist,
            'deviceCode' => $channelBan,
            'isNew' => $this->isNew,
            'isOpenPay' => intval($this->isOpenPay),
        ];
        if (isset($accountInfo['is_gm'])) $data['isGm'] = intval($accountInfo['is_gm']);
        if (intval($this->isChannelGm) == 1) $data['isGm'] = 1;
        return $data;
    }

    /**
     * 区服信息结构体
     * @param $server
     * @param $actor
     * @return array
     */
    public function serverStruct($server, $actor)
    {
        $data = [
            'sid' => $server['sid'],
            'sname' => $server['name'],
            'sgid' => $server['sgid'],
            'host' => $server['frontip'],
            'port' => $server['frontport'],
            'recommend' => $server['is_recommend'],
            'status' => $server['status'],
            'tag' => $server['tag'],
        ];
        if ($actor) $data['actor'] = $actor;
        if ($server['open_time'] >= date('Y-m-d H:i:s')) $data['openDateTime'] = strtotime($server['open_time']);
        return $data;
    }

    /**
     * 角色信息结构体
     * @param $actor
     * @return array
     */
    public function actorStruct($actor)
    {
        if (!isset($actor['actor_id']) || !isset($actor['actor_name'])) return [];
        return [
          'actorId' => $actor['actor_id'],
          'actorName' => $actor['actor_name'],
          'scene' => $actor['scene'],
        ];
    }

    public function channelInfo()
    {
        return [];
    }

    public function setGmAccount()
    {
        return false;
    }

    /**
     * 初始化区服条件
     * @param $isWhitelist
     * @param $cpid
     * @return string
     */
    public function initServerMap($isWhitelist, $cpid): string
    {
        $where = ' is_display=1 and ';
        // 白名单账号，可以看到全部白名单的区服
        if ($isWhitelist) {
            // 查询是否显示全服
            $res = $this->model('Whitelist')->getByAccount($this->account, $this->deviceCode, false);

            if ($res[0]['show_all_server']) {
                $this->serverWhere = '1 ';
                return $this->serverWhere;
            }
        }

        $where .= $this->getChannelServerMap($where, $cpid);

        if ($this->isDebug) $this->logfile("debug where: {$where}");
        $this->serverWhere = $where;
        return $where;
    }

    public function getChannelServerMap($where, $cpid, $cid='')
    {
        !$cid && $cid = realCID();
        $ChannelModel = $this->model('Channel');
//        // 获取渠道数据
//        $channel = $ChannelModel->getChannelInfo($cid);
//        $this->cid = $channel['cid'];
        // 获取包数据
        $channelPackage = $ChannelModel->getChannelPackageInfoByCpid($cpid);
        // 是否有包的大区id
        if ($channelPackage && $channelPackage['srid']) {
            $srid = $channelPackage['srid']; // 这里的格式有可能是 3,10;4,11/3,10/3
            // 检测是否有逗号，无则表示只选中一个大区，保留不做处理
            if (strpos($srid, ",") !== false) {
                $w = [];
                // 首先根据分号分割
                $g = explode(';', $srid);
                foreach ($g as $item) {
                    list($sr, $s) = explode(',', $item);
                    $w[] = " (srid={$sr} and sr_correlation_id>={$s}) ";
                }
                $where .= '('.implode(' OR ', $w).')';
            } else {
                $where .= " srid='$srid'";
            }
        } else {
            // 是否有渠道的大区id
            if ($this->srid){
                $srid = $this->srid;
                $where .= " srid in ($srid)";
            } else {
                $channel = $this->model('Channel')->getChannelInfo($cid, false);
                $srid = $channel['srid'] ?? 0;
                $where .= " srid in ($srid)";
            }
        }
        $this->srid = $srid;
        return $where;
    }

    public function initChannelParam($channel){
        if ($channel) {
            $this->cid = $channel['cid'];
            $this->srid = $channel['srid'];
            $this->isChannelGm = $channel['is_gm'];
            $this->channelConfig = $channel['config'];
            $this->isOpenPay = $channel['is_open_pay'];
        }
    }
    
    public function getSuperLoginParams()
    {
        $this->logfile('###########------ super login start ' . PFORM_NAME . ' ------##########');
        $this->superId;

        if (empty($this->superId)) return false;

        $as = explode('-', $this->superId);
        $old_cid = $as[0];//账户内的渠道（不一定是注册渠道或登录渠道
        $this->account = $this->superId;
        //最后的账号
        //$base = $this->model('Account')->getLastLoginAccountMChannel($this->account)[0] ?? [];
        $base = $this->model('Actor')->getLastDauInfo($this->account);

        $GLOBALS['GAME_ID'] =  $base['cpid'] ?? '';
        $cid = $base['cid'] ?:$old_cid;//最后的渠道
        $this->cid = $cid;
        $this->ccid = $base['ccid'] ?? '';;
        $GLOBALS['CID'] = $GLOBALS['PFORM_NAME'] = $cid;
        $ChannelModel = $this->model('Channel');
        $channel = $ChannelModel->getChannelInfo($cid);//
        $this->initChannelParam($channel);
        $this->ccid =  ($base['ccid'] ?? $this->get('channel_id'));
        $this->logfile('###########------ super login srid ' . $this->srid . ' ------##########');
        $this->logfile('###########------ super login cid ' . $this->cid . ' ------##########');
        $this->logfile('###########------ super login cpid ' . $this->cpid . ' ------##########');
        $this->logfile('###########------ super login ccid ' . $this->ccid . ' ------##########');
        $this->logfile('###########------ super login end ' . PFORM_NAME . ' ------##########');
    }
    public function getLoginParams()
    {
        $this->logfile('################# login start ' . PFORM_NAME . ' ################');
        $this->initLoginParams();

        $ChannelModel = $this->model('Channel');
        // 获取渠道数据
        $channel = $ChannelModel->getChannelInfo();
        $this->initChannelParam($channel);
        $this->logfile('################# login cid ' . $this->cid . ' ################');
        $this->logfile('################# login CID ' . CID . ' ################');
        // 修改账号account格式：映射后渠道ID_openId
        $this->account = $ChannelModel->realAccount($this->account,$this->cid);
        if(empty($this->account)){
            $this->logfile("empty account");
            return false;
        }
    }

    /**
     * 生成验签密码
     * @param $account
     * @param $whitelist
     * @return string
     */
    public function generateVerifyCode($account, $whitelist)
    {
        $code = md5(uniqid(rand(), true));

        $values = [
            $code,
            $whitelist // 只放redis 给后端使用
        ];

        $key = $account;
        $res = $this->redis->set($key, implode(',', $values), 2*60*60); // 过期时间2个钟
        $this->logfile("generate verify code success.key:{$key} res:{$res}");
        return $code;
    }

    public function setAccountSridRedis($account, $whitelist, $srid)
    {
        $key = 'srid-'.$account;
        $value = $whitelist.'_'.$srid;
        $res = $this->redis->set($key, $value, 2*60*60); // 过期时间2个钟
        $this->logfile("generate account srid redis success.key:{$key} value:$value res:{$res}");
    }

    public function getAccountRedis($account)
    {
        $value = $this->redis->get('srid-'.$account);
        return $value ? explode('_', $value) : [];
    }

    public function __get($name = '')
    {
        if (in_array($name, ['db', 'cache', 'config', 'redis'])) {
            return parent::__get($name);
        }
        return $this->$name = $this->get($name);
    }

    /**
     * 初始化选服页参数
     *
     * @return void
     */
    abstract protected function initServerListParams();

    /**
     * 初始化登录页参数
     *
     * @return void
     */
    abstract protected function initLoginParams();

    public function DEVLoginInfo()
    {
        if(APP_DEV==2){
            $debug = PF_PATH.'debug.php';
            if(file_exists($debug)){
                $debugData = include_once $debug;
            }else{
                //dd(PF_PATH);
            }

            foreach ($debugData['request'] ?? [] as $field => $value){
                $_GET[$field] = $value;//初始化请求参数
            }
            return $debugData['userInfo'] ?? [];
        }
        return [];

    }

}